/**
 * 报销单核销弹窗 前端分页
 * 核销金额修改实时存在前端data中，确定时把勾选的dto传给后台
 * create by Wu
 */
import React from 'react'
import { connect } from 'react-redux'
import {deepFullCopy, messages, queryCurrencyPrecision} from "share/common";
import { Form, Modal, message, InputNumber, Table, Alert, Button, Popover } from "antd";
import expenseReportService from 'containers/expense-report/expense-report.service'
import 'styles/expense-report/template/write-off-modal.scss'
import moment from "moment/moment";
import writeOffImg from "images/expense-report/writeOff.png";
import accurateFloat from 'containers/expense-report/template/accurate-float';
const FormItem = Form.Item;

class WriterOffModal extends React.Component{
  constructor(props){
    super(props);
    this.state = {
      data: [],
      columns: [
        {title: messages('expense-parent-report.key138')/*交易日期*/, dataIndex: 'payDate', render: value => value ? moment(value).format('YYYY-MM-DD') : '-', width: 100},
        {title: messages('expense-parent-report.key168')/*付款流水号*/, dataIndex: 'transactionDetailCode', render: value => <Popover content={value} placement={'topLeft'}>{value}</Popover>},
        {title: messages('expense-parent-report.key139')/*借款单号*/, dataIndex: 'businessCode', render: value => <Popover content={value} placement={'topLeft'}>{value}</Popover>},
        {title: messages('expense-parent-report.key140')/*借款类型*/, dataIndex: 'loanTypeName', width: '10%', align: 'center', render: (value, record) =>
            record.isCompulsoryWriteOff ? <span style={{color: 'red'}}>{value}</span> : value},
        {title: messages('expense-parent-report.key141')/*借款事由*/, dataIndex: 'remark',render: value => <Popover content={value} placement='topLeft'>{value}</Popover>},
        {title: messages('common.currency')/*币种*/, dataIndex: 'currencyCode', width: 48},
        {title: messages('common.total.amount')/*总金额*/, dataIndex: 'amount', width: '8%', render:(value,record) => this.filterMoney(value,queryCurrencyPrecision(record.currencyCode))},
        {title: messages('expense-parent-report.key55')/*可还款金额*/, dataIndex: 'enableWriteOffAmount', width: '11%', render:(value,record) => this.filterMoney(value,queryCurrencyPrecision(record.currencyCode))},
        {title: messages('expense-parent-report.key142')/*本次核销额*/, dataIndex: 'repaymentValue', render: (value,record) => {
            return (
              <FormItem>
                {props.form.getFieldDecorator(`repayment-${record.transactionDetailId}`, {
                  initialValue: value
                })(
                  <InputNumber className="no-input-style" disabled={this.state.single}
                               onChange={(value) => this.handleOnchange(value,record.transactionDetailId)}
                               min={0} precision={queryCurrencyPrecision(record.currencyCode)}/>
                )}
              </FormItem>
            )
          }}
      ],
      pagination: {
        total: 0,
        defaultPageSize: 5
      },
      copyData: [],
      rowSelection: {
        type: props.profile['finance.multi.writeoff'] ? 'checkbox' : 'radio',
        selectedRowKeys: [],
        onChange: this.onSelectChange,
        onSelect: this.onSelectItem,
        onSelectAll: this.onSelectAll
      },
      selectIds: [],
      writeOffAmount: null,
      realPaymentAmount: null,
      saveLoading: false,
      single: !props.profile['finance.multi.writeoff'],
      baseCurrency: props.company.baseCurrency,
      loading: false
    };
  }

  componentDidMount(){
    const { companyOID, recordInfo, expenseReportApplicationDTOS, setOfBooksId, corporationOID, formCode } = this.props;
    const { rowSelection } = this.state;
    let params = {
      companyOID: companyOID,
      payeeId: recordInfo ? recordInfo.payeeId : null,
      currencyCode: recordInfo ? recordInfo.currencyCode : null,
      paymentScheduleId: recordInfo ? recordInfo.id : null,
      setOfBooksId,
      corporationOID,
      formCode
    };
    if(this.props.profile['ALL.ER.DefaultLoan.Forcible']){
      let applicationOIDs = [];
      expenseReportApplicationDTOS.map(item => {
        applicationOIDs.push(item.applicationOID);
      });
      params.applicationOIDs = applicationOIDs;
    }
    this.setState({loading: true});
    expenseReportService.getWriteOffList(params).then(res => {
      let temp = [];
      res.data.map(item => {
        item.repaymentValue && (temp.push(item.transactionDetailId));
      });
      rowSelection.selectedRowKeys = temp;
      this.setState({
        data: res.data,
        copyData: res.data,
        selectIds: temp,
        writeOffAmount: recordInfo.writeOffAmount,
        realPaymentAmount: recordInfo.realPaymentAmount,
        rowSelection,
        loading: false
      });
    }).catch(e => {
      this.setState({loading: false});
      message.error(e.response.data.message);
    })
  }

  componentWillReceiveProps(nextProps) {
    if(!nextProps.visible){
      this.setState({data: [],copyData: [],selectIds: [],writeOffAmount: null, realPaymentAmount: null});
    }
  }

  handleOnchange = (value,transactionDetailId) => {
    let { copyData, writeOffAmount, realPaymentAmount } = this.state;
    const { recordInfo } = this.props;
    let fixedNumber = queryCurrencyPrecision(recordInfo.currencyCode);
    let temp = {};
    copyData.map((item,index) => {
      if(item.transactionDetailId === transactionDetailId){
        if(typeof value === 'number' || !value){
          !value && (value = 0);
          let rate = this.getRate(item);
          let baseValue = Number(accurateFloat.multiply(Number(item.repaymentValue),rate).toFixed(fixedNumber));
          writeOffAmount = accurateFloat.subtract(writeOffAmount,baseValue);
          let copyWriteOffAmount = deepFullCopy(writeOffAmount);
          realPaymentAmount = accurateFloat.add(realPaymentAmount,baseValue);
          let nowValue = Number(accurateFloat.multiply(Number(value),rate).toFixed(fixedNumber));
          writeOffAmount = accurateFloat.add(writeOffAmount,nowValue);
          if(0 <= writeOffAmount && writeOffAmount <= recordInfo.amount){
            item.repaymentValue = value;
            this.changeRowSelected(value,transactionDetailId);
            realPaymentAmount = accurateFloat.subtract(realPaymentAmount,nowValue);
            copyData[index] = item;
          }else if(writeOffAmount > recordInfo.amount){
            let res = (recordInfo.amount - copyWriteOffAmount) / this.getRate(item);
            writeOffAmount = recordInfo.amount;
            realPaymentAmount = 0;
            this.changeRowSelected(res,transactionDetailId);
            item.repaymentValue = res.toFixed(queryCurrencyPrecision(item.currencyCode)).toString();
            temp[`repayment-${item.transactionDetailId}`] = res.toFixed(queryCurrencyPrecision(item.currencyCode)).toString();
          }
        }
      }
    });
    this.setState({copyData, writeOffAmount: Math.abs(writeOffAmount), realPaymentAmount: Number(realPaymentAmount)},() => {
      Object.keys(temp).length > 0 && this.props.form.setFieldsValue(temp);
    });
  };

  getLeastAmount = (str,num) => {
    let res = '';
    if (num === 0) {
      res = Math.floor(str);
    } else {
      let arr = str.split('.');
      res = `${arr[0]}${arr[1] ? `.${arr[1].substr(0,num)}` : ''}`;
    }
    return res;
  };

  getRate = item => {
    const { baseCurrency } = this.state;
    const { recordInfo } = this.props;
    let rate = 1;
    item.currencyCode === baseCurrency && recordInfo.currencyCode !== baseCurrency && (rate = 1 / recordInfo.currencyRate);
    item.currencyCode !== baseCurrency && recordInfo.currencyCode === baseCurrency && (rate = item.exchangeRate);
    return rate;
  };

  changeRowSelected = (value,transactionDetailId) => {
    let {rowSelection,selectIds} = this.state;
    value && rowSelection.selectedRowKeys.filter(key => key === transactionDetailId).length === 0 && rowSelection.selectedRowKeys.push(transactionDetailId);
    value && selectIds.filter(key => key === transactionDetailId).length === 0 && selectIds.push(transactionDetailId);
    if(!value){
      rowSelection.selectedRowKeys.map((key,index) => {
        key === transactionDetailId && (rowSelection.selectedRowKeys[index] = undefined);
      });
      rowSelection.selectedRowKeys = rowSelection.selectedRowKeys.filter(ids => !!ids);
      selectIds.map((key,index) => {
        key === transactionDetailId && (selectIds[index] = undefined);
      });
      selectIds = selectIds.filter(ids => !!ids);
    }
    this.setState({rowSelection, selectIds});
  };

  handleTableChange = () => {
    const { copyData, page } = this.state;
    copyData.map((item,index) => {
      let temp = {};
      temp[`repayment-${item.transactionDetailId}`] = item.repaymentValue;
      if((index >= page * 5) || (index <= (page * 5 + 4))){
        this.props.form.setFieldsValue(temp);
      }
    });
  };

  handleOk = () => {
    const { copyData, selectIds } = this.state;
    const { recordInfo, expenseReportOID, userOid } = this.props;
    let selectArray = [];
    selectIds.map(ids => {
      selectArray.push(copyData.filter(item => item.transactionDetailId === ids)[0]);
    });
    let params = [];
    selectArray.map(item => {
      let temp = {};
      temp.loanLineId = item.id;
      temp.paymentScheduleId = recordInfo.id;
      temp.curreny = item.currencyCode;
      item.repaymentValue && (temp.repaymentValue = Number(item.repaymentValue));
      temp.expenseReportOid = expenseReportOID;
      temp.userOid = userOid;
      item.repaymentValue && (temp.paymentWriteOffAmount = Number((Number(item.repaymentValue) * this.getRate(item)).toFixed(queryCurrencyPrecision(recordInfo.currencyCode))));
      temp.paymentRate = recordInfo.currencyRate;
      temp.paymentCurrency = recordInfo.currencyCode;
      temp.transactionDetailId = item.transactionDetailId;
      params.push(temp);
    });
    if(params.filter(item => item.repaymentValue && item.repaymentValue >= 0).length === params.length){
      this.setState({saveLoading: true});
      expenseReportService.confirmWriteOff(recordInfo.id,params).then(() => {
        this.setState({saveLoading: false});
        this.props.close(true);
      }).catch(e => {
        this.setState({saveLoading: false});
        message.error(e.response.data.message);
      })
    }else{
      message.error(messages('expense-parent-report.key144')/*勾选中的请输入核销金额*/);
    }
  };

  onSelectChange = (selectedRowKeys) => {
    let { rowSelection } = this.state;
    rowSelection.selectedRowKeys = selectedRowKeys;
    this.setState({ rowSelection });
  };

  onSelectItem = (record, selected) => {
    let { selectIds, realPaymentAmount, single, writeOffAmount, copyData } = this.state;
    const { recordInfo } = this.props;
    if(selected){
      if(single){
        selectIds.map(transactionDetailId => {
          let res = {};
          copyData.map(item => {
            if(item.transactionDetailId === transactionDetailId){
              let changeValue = Number((Number(item.repaymentValue) * this.getRate(item)).toFixed(queryCurrencyPrecision(recordInfo.currencyCode)));
              realPaymentAmount += changeValue;
              writeOffAmount -= changeValue;
              item.repaymentValue = undefined;
            }
          });
          res[`repayment-${transactionDetailId}`] = undefined;
          this.props.form.setFieldsValue(res);
        });
        selectIds = [];
      }
      selectIds.filter(item => item === record.transactionDetailId).length === 0 && selectIds.push(record.transactionDetailId);
      let temp = {};
      let tempRealPaymentAmount = realPaymentAmount / this.getRate(record);
      let res = (tempRealPaymentAmount <= record.enableWriteOffAmount ? tempRealPaymentAmount : record.enableWriteOffAmount);
      res = Number(this.getLeastAmount(res.toString(),queryCurrencyPrecision(record.currencyCode)));
      temp[`repayment-${record.transactionDetailId}`] = res.toString();
      this.setState({copyData, writeOffAmount, realPaymentAmount},() => {
        this.props.form.setFieldsValue(temp);
        this.handleOnchange(res, record.transactionDetailId);
      })
    } else {
      selectIds.map((item,index) => {
        item === record.transactionDetailId && (selectIds[index] = undefined);
      });
      selectIds = selectIds.filter(item => !!item);
      let temp = {};
      temp[`repayment-${record.transactionDetailId}`] = undefined;
      this.props.form.setFieldsValue(temp);
      this.handleOnchange(0,record.transactionDetailId);
    }
    this.setState({selectIds});
  };

  onSelectAll = (selected, selectedRows, changeRows) => {
    let { selectIds, realPaymentAmount, writeOffAmount, copyData } = this.state;
    const { recordInfo } = this.state;
    if(selected){
      changeRows.map(item => {
        selectIds.filter(ids => ids === item.transactionDetailId).length === 0 && selectIds.push(item.transactionDetailId);
        let temp = {};
        let tempRealPaymentAmount = realPaymentAmount / this.getRate(item);
        let res = (tempRealPaymentAmount <= item.enableWriteOffAmount ? tempRealPaymentAmount : item.enableWriteOffAmount);
        res = Number(this.getLeastAmount(res.toString(),queryCurrencyPrecision(item.currencyCode)));
        let changeValue = Number((res * this.getRate(item)).toFixed(queryCurrencyPrecision(recordInfo,item.currencyCode)));
        writeOffAmount += changeValue;
        realPaymentAmount = accurateFloat.subtract(realPaymentAmount, changeValue);
        temp[`repayment-${item.transactionDetailId}`] = res.toString();
        copyData.map(ids => {
          ids.transactionDetailId === item.transactionDetailId && (item.repaymentValue = res.toString());
        });
        this.props.form.setFieldsValue(temp);
      });
    } else {
      changeRows.map(item => {
        selectIds.map((ids,index) => {
          if(item.transactionDetailId === ids){
            selectIds[index] = undefined;
            let temp = {};
            temp[`repayment-${ids}`] = undefined;
            this.props.form.setFieldsValue(temp);
          }
        });
        copyData.map((ids) => {
          if(ids.transactionDetailId === item.transactionDetailId){
            let res = Number((Number(ids.repaymentValue) * this.getRate(item)).toFixed(queryCurrencyPrecision(recordInfo,item.currencyCode)));
            writeOffAmount -= res;
            realPaymentAmount += res;
            ids.repaymentValue = undefined;
          }
        })
      });
      selectIds = selectIds.filter(item => !!item);
    }
    this.setState({selectIds, writeOffAmount: Math.abs(writeOffAmount), realPaymentAmount, copyData});
  };

  clearSelect = () => {
    let {  selectIds } = this.state;
    selectIds.map(item => {
      setTimeout(() => {
        let temp = {};
        temp[`repayment-${item}`] = undefined;
        this.props.form.setFieldsValue(temp);
        this.handleOnchange(0,item);
      }, 50);
    });
    this.setState({ selectIds: [] });
  };

  render(){
    const { data, columns, pagination, rowSelection, writeOffAmount, realPaymentAmount, saveLoading, loading, selectIds, copyData } = this.state;
    const { visible, recordInfo } = this.props;
    let res = [];
    copyData.map(item => {
      selectIds.indexOf(item.transactionDetailId) > -1 && (res.push(`${item.currencyCode} ${this.filterMoney(item.repaymentValue,queryCurrencyPrecision(item.currencyCode),true)}*${this.getRate(item)}`));
    });
    return(
      <Modal visible={visible}
             width={900}
             className={'write-off'}
             footer={<div>
               <Button onClick={this.clearSelect}>{messages('expense-parent-report.key169')/*清除已选*/}</Button>
               <Button onClick={() => this.props.close()}>{messages('common.cancel')/*取消*/}</Button>
               <Button type='primary' onClick={this.handleOk} loading={saveLoading}>{messages('common.ok')/*确定*/}</Button>
             </div>}
             onCancel={() => this.props.close()}
             title={messages('expense-parent-report.key145')/*核销借款单*/}>
        <Alert message={<div style={{marginLeft:'15px'}}>
          <div>{messages('expense-parent-report.key146')/*核销金额不能超过计划付款行金额*/}</div>
          <div>{messages('expense-parent-report.key212')/*借款类型红色的为强制核销欠款，请优先核销*/}</div>
        </div>} type="warning" showIcon style={{marginBottom: '8px'}} />
        <div style={{fontSize: '16px', fontWeight:'600',lineHeight: '30px'}}> {messages('expense-parent-report.key147')/*计划付款行金额*/}：
          {recordInfo ? recordInfo.currencyCode : '-'}&nbsp;&nbsp;{recordInfo ? this.filterMoney(recordInfo.amount,queryCurrencyPrecision(recordInfo.currencyCode)) : '-'}
        </div>
        <div style={{marginBottom:'10px'}}> {messages('expense-parent-report.key148')/*已核销金额*/}：
          {
            selectIds.length > 0 && <Popover content={res.join('+')} placement={'topLeft'}>
              <img src={writeOffImg} style={{width: '40px', height: 'auto'}}/>
            </Popover>
          }
          {recordInfo ? recordInfo.currencyCode : '-'}&nbsp;&nbsp;{typeof writeOffAmount === 'number' ? this.filterMoney(writeOffAmount,queryCurrencyPrecision(recordInfo.currencyCode)) : '-'}
          &nbsp;&nbsp;&nbsp;&nbsp; {messages('expense-parent-report.key149')/*可核销金额*/}：
          {recordInfo ? recordInfo.currencyCode : '-'}&nbsp;&nbsp;{typeof realPaymentAmount === 'number' ? this.filterMoney(realPaymentAmount,queryCurrencyPrecision(recordInfo.currencyCode)) : '-'}
        </div>
        <Table dataSource={data}
               rowKey="transactionDetailId"
               loading={loading}
               rowSelection={rowSelection}
               className={'write-off-table'}
               pagination={pagination}
               size={'small'}
               onChange={this.handleTableChange}
               columns={columns}
               bordered/>
      </Modal>
    )
  }
}

function mapStateToProps(state){
  return {
    profile: state.login.profile,
    company: state.login.company
  }
}

WriterOffModal.propTypes = {
  visible: React.PropTypes.bool,
  close: React.PropTypes.func,
  recordInfo: React.PropTypes.object,
  companyOID: React.PropTypes.string,
  expenseReportOID: React.PropTypes.string,
  userOid: React.PropTypes.string,
  expenseReportApplicationDTOS: React.PropTypes.array,
  setOfBooksId: React.PropTypes.string,
  corporationOID: React.PropTypes.string
};

WriterOffModal.defaultProps = {
  close: () => {}
};

const wrappedWriterOffModal = Form.create()(WriterOffModal);

export default connect(mapStateToProps)(wrappedWriterOffModal);
